/**
 * Copyright 2006 Bosco Curtu
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * 
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. 
 * 
 * See the License for the specific language governing permissions and limitations 
 * under the License.
*/

package com.bcurtu.james;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Vector;

import org.apache.commons.pool.ObjectPool;
import org.apache.log4j.Logger;

import com.bcurtu.james.exceptions.JamesException;

public class JamesManager {

	private Logger log =Logger.getLogger(this.getClass());
	
	private ObjectPool pool;
	private String adduser;
	private String adduserok;
	private String setforward;
	private String setforwardok;
	private String deluser;
	private String deluserok;
	private String veruser;
	private String veruserfree;
	private String veruseroccupied;
	private String shutdown;
	private String listusers;

	public ObjectPool getPool() {
		return pool;
	}

	public void setPool(ObjectPool pool) {
		this.pool = pool;
	}
	
	public String getListusers() {
		return listusers;
	}

	public void setListusers(String listusers) {
		this.listusers = listusers;
	}

	public String getShutdown() {
		return shutdown;
	}

	public void setShutdown(String shutdown) {
		this.shutdown = shutdown;
	}

	public String getDeluser() {
		return deluser;
	}

	public void setDeluser(String deluser) {
		this.deluser = deluser;
	}

	public String getDeluserok() {
		return deluserok;
	}

	public void setDeluserok(String deluserok) {
		this.deluserok = deluserok;
	}

	public String getVeruser() {
		return veruser;
	}

	public void setVeruser(String veruser) {
		this.veruser = veruser;
	}

	public String getVeruserfree() {
		return veruserfree;
	}

	public void setVeruserfree(String veruserfree) {
		this.veruserfree = veruserfree;
	}

	public String getVeruseroccupied() {
		return veruseroccupied;
	}

	public void setVeruseroccupied(String veruseroccupied) {
		this.veruseroccupied = veruseroccupied;
	}

	public String getAdduser() {
		return adduser;
	}

	public void setAdduser(String adduser) {
		this.adduser = adduser;
	}

	public String getAdduserok() {
		return adduserok;
	}

	public void setAdduserok(String adduserok) {
		this.adduserok = adduserok;
	}

	public String getSetforward() {
		return setforward;
	}

	public void setSetforward(String setforward) {
		this.setforward = setforward;
	}

	public String getSetforwardok() {
		return setforwardok;
	}

	public void setSetforwardok(String setforwardok) {
		this.setforwardok = setforwardok;
	}

	public void createAccount(String left, String forward) throws Exception{
		Socket s=(Socket)pool.borrowObject();
		InputStream is=s.getInputStream();
		OutputStream os=s.getOutputStream();
		
		BufferedReader bf=new BufferedReader(new InputStreamReader(is));

		String cmd=adduser.replaceAll("USER",left).replaceAll("PWD","xxxx")+"\n";
		os.write(cmd.getBytes());
		
		String line=bf.readLine();
		log.debug(line);

		String respok=adduserok.replaceAll("USER",left);
		if (!respok.equals(line)){
			pool.returnObject(s);
			throw new JamesException(line,JamesException.AliasError);
		}
		
		cmd=setforward.replaceAll("USER",left).replaceAll("EMAIL",forward)+"\n";
		os.write(cmd.getBytes());
		
		line=bf.readLine();
		log.debug(line);

		respok=setforwardok.replaceAll("USER",left).replaceAll("EMAIL",forward);
		if (!respok.equals(line)){
			pool.returnObject(s);
			throw new JamesException(line,JamesException.ForwardError);
		}
		
		pool.returnObject(s);
		
	}

	public void deleteAccount(String left) throws Exception{
		Socket s=(Socket)pool.borrowObject();
		InputStream is=s.getInputStream();
		OutputStream os=s.getOutputStream();
		
		BufferedReader bf=new BufferedReader(new InputStreamReader(is));

		String cmd=deluser.replaceAll("USER",left)+"\n";
		os.write(cmd.getBytes());
		
		String line=bf.readLine();
		log.debug(line);

		String respok=deluserok.replaceAll("USER",left);
		if (!respok.equals(line)){
			pool.returnObject(s);
			throw new JamesException(line,JamesException.AliasError);
		}
		pool.returnObject(s);		
	}

	/**
	 * It throws an Exception in case that the Account ALREADY exists!
	 * @param left
	 * @throws Exception
	 */
	public boolean verifyFreeAccount(String left) throws Exception{
		Socket s=(Socket)pool.borrowObject();
		InputStream is=s.getInputStream();
		OutputStream os=s.getOutputStream();
		
		BufferedReader bf=new BufferedReader(new InputStreamReader(is));

		String cmd=veruser.replaceAll("USER",left)+"\n";
		os.write(cmd.getBytes());
		
		String line=bf.readLine();
		log.debug(line);

		String respok=veruserfree.replaceAll("USER",left);
		if (!respok.equals(line)){
			pool.returnObject(s);
			throw new JamesException(line,JamesException.AliasError);
		}
		pool.returnObject(s);
		return  true;
	}

	/**
	 * It throws an Exception in case that the Account DOES NOT exist!
	 * @param left
	 * @throws Exception
	 */
	public boolean verifyExistingAccount(String left) throws Exception{
		Socket s=(Socket)pool.borrowObject();
		InputStream is=s.getInputStream();
		OutputStream os=s.getOutputStream();
		
		BufferedReader bf=new BufferedReader(new InputStreamReader(is));

		String cmd=veruser.replaceAll("USER",left)+"\n";
		os.write(cmd.getBytes());
		
		String line=bf.readLine();
		log.debug(line);

		String respok=veruseroccupied.replaceAll("USER",left);
		if (!respok.equals(line)){
			pool.returnObject(s);
			throw new JamesException(line,JamesException.AliasError);
		}
		pool.returnObject(s);		
		return  true;
	}

	public void shutdownJames() throws Exception{
		Socket s=(Socket)pool.borrowObject();
		OutputStream os=s.getOutputStream();
		

		String cmd=getShutdown()+"\n";
		os.write(cmd.getBytes());
		
		pool.returnObject(s);		
	}
	
	public void cleanAllAccounts() throws Exception{
		Socket s=(Socket)pool.borrowObject();
		InputStream is=s.getInputStream();
		OutputStream os=s.getOutputStream();
		
		BufferedReader bf=new BufferedReader(new InputStreamReader(is));

		String cmd=listusers+"\n";
		os.write(cmd.getBytes());
		
		String line=bf.readLine();
		log.debug(line); //Existing accounts XXXX
		
		String accounts=line.substring("Existing accounts".length()).trim();
		int accs=Integer.parseInt(accounts);

		Vector v=new Vector();
		for (int i=0;i<accs;i++){
			line=bf.readLine();
			v.add(line.substring("user: ".length()));
		}
		
		for (int i=0;i<accs;i++){
			deleteAccount((String)v.get(i));
		}
		
		pool.returnObject(s);		
	}


}
